﻿#ifndef  CONSOLEGAMEBASE_H
#define CONSOLEGAMEBASE_H

#include <memory>

#include <consoleimage.h>
#include <gamestate.h>
#include <playercontroller.h>
#include <actor.h>
#include <gameinstance.h>

class ConsoleGameBase:public ThreadSafe::ThreadSafeBase
{
public:
	enum Role
	{
		Role_None = 0,
		Role_Server,
		Role_Client
	};

	enum RunMode
	{
		RM_None = 0,
		RM_Single,
		RM_ListenServer,
		RM_PureServer,
		RM_Client
	};


	ConsoleGameBase();
	~ConsoleGameBase();

	void startAsSingle();
	void startAsServer(int port);
	void startAsClient(std::string ip,int port);
	void startAsListenServer(int port);
	

	void end();

	Role GetRole() const;

public:
	//Actor Operation
	Actor* GetActor(std::string Name);
	std::vector<Actor*> GetAllActor();

	//以公有方式创建对象，所有端可见，客户端调用会返回空指针
	template<typename T>
	T* PublicSpawnActor() {
		return dynamic_cast<T*>(PublicSpawnActor(T::staticMetaInfo()));
	}
	Actor* PublicSpawnActor(MetaInfo m);

	//以私有方式创建对象，仅本端可见，服务端和客户端均可调用
	template<typename T>
	T* PrivateSpawnActor() {
		return dynamic_cast<T*>(PrivateSpawnActor(T::staticMetaInfo()));
	}
	Actor* PrivateSpawnActor(MetaInfo m);

public:
	std::chrono::system_clock::time_point GetWorldTime();
	std::chrono::system_clock::duration GetWorldTimeDelta();
	void SetMaxFPS(int fps);
	int GetMaxFPS() const;

public:
	//Player Option
	PlayerContorller* GetCurrentController();//获取当前控制器，纯服务端为NULL
	std::vector<PlayerContorller*> GetPlayerController();//获取所有控制器,在服务端可以获取所有玩家控制器，在客户端只能获取自身控制器



	//Type Registrition
protected:
	template<typename T>
	void SetControllerType() {
		SetControllerType(T::staticMetaInfo());
	}
	void SetControllerType(MetaInfo meta);

	template<typename T>
	void SetGameStateType() {
		SetGameStateType(T::staticMetaInfo());
	}
	void SetGameStateType(MetaInfo meta);

	template<typename T>
	void RegisterActor() {
		RegisterActor(T::staticMetaInfo());
	}
	void RegisterActor(MetaInfo meta);

	template<typename T>
	void SetGameInstanceType() {
		SetGameInstanceType(T::staticMetaInfo());
	}
	void SetGameInstanceType(MetaInfo meta);

protected:
	virtual	void paint(ConsoleImage& image) = 0;
	virtual void gameBegin() = 0;
private:
	void start();
	Actor* CreateActor(MetaInfo m);
	void RegisterActor(Actor* a);
	void posttime();
	void timeout();
	void doFrameWork();
	//启动和关闭帧事件
	void EnableFrameEvent(Actor* a);
	void DisableFrameEvent(Actor* a);
	void OnGameBegin();
	void OnGameInstanceReady();
	void OnPlayReady();
	void OnGameEnd();
	void OnPlayerAdded(PlayerId);
	void OnActorSpawned(Actor* a);
	void ReplicaSpawn(std::string shareName,std::string className);
	std::string AllocShareName();
private:
	struct Private;
	std::unique_ptr<Private> _P;

	friend class Actor;
};

#endif // ! CONSOLEGAMEBASE_H
